#ifndef __LOGGER_H__
#define __LOGGER_H__ 1

#define COMPATIBILITY_LOGGER 1

/* log-flags, these are optional */
#define L_DATE 0x0001 /* append date */
#define L_TIME 0x0002 /* append time (only used with L_DATE) */
#define L_EXIT 0x0004 /* exit program after log */

#define L_DATETIME (L_DATE | L_TIME) /* use this if you want L_TIME :) */

/* log-levels */
#define LL_DEBUG 0x0008 /* default */
#define LL_WARN 0x0010 /* not critical, maybe important */
#define LL_ERR 0x0020 /* maybe critical */

#define LL_EMERG (LL_ERR | L_EXIT | LT_BOTH) /* emergency */

#ifdef COMPATIBILITY_LOGGER
/* log-targets */
#define LT_LOGFILE 0x0080 /* default */
#define LT_STDERR 0x0100 /* use stderr instead of logfile */
#define LT_SYSLOG 0x0200 /* log to syslog */
#endif

#define LT_BOTH (LT_LOGFILE | LT_STDERR) /* use logfile and stderr */

#include <fstream>
#include <iostream>

#include "ui_constants.h"

/* initialize the logger, if pFlags != 0, the the given flags are taken as
 * default instead of the system-default ones */
#ifdef COMPATIBILITY_LOGGER
int init_log(const char* pLogFile, unsigned pFlags);
#endif
int init_log(unsigned int pFlags, const char* pLogFile = NULL);

/* the loggers' heart, if pFlags != 0, they are added to the default ones.
 * pSource denotes the sender of this log message (i.e. the part of the program,
 * if this can be determined...) */
int printl_raw(bool pConsoleOnly, unsigned int pFlags, const char* pSource, const char* pFormat, va_list pArgList);
int printl_console(unsigned int pFlags, const char* pSource, const char* pFormat, ...);
int printl(unsigned int pFlags, const char* pSource, const char* pFormat, ...);

/* cleanup the logger, flush buffers, close files, etc. */
int cleanup_log();

class CLogger
{
	public:
		static CLogger* getInstance();
		static int destroy();

		/* logging format */
		static const unsigned int LOG_DATE;
		static const unsigned int LOG_TIME;
		/* logging output facilities */
		static const unsigned int LOG_FILE;
		static const unsigned int LOG_STDERR;
		static const unsigned int LOG_SYSLOG;
		static const unsigned int LOG_SOCKET;

		static const unsigned int sDefaultFlags;

		int init_log(unsigned int pFlags, const char* pLogFile = NULL);
		int change_flags(unsigned int pFlags);
		int printl_console(enum ELogLevel pLogLevel, const char* pSource, const char* pFormat, ...);
		int printl(enum ELogLevel pLogLevel, const char* pSource, const char* pFormat, ...);
#ifdef COMPATIBILITY_LOGGER
		int printl_raw(bool pConsoleOnly, enum ELogLevel pLogLevel, const char* pSource, const char* pFormat, va_list pArgList);
#endif

	private:
		CLogger();
		virtual ~CLogger();
		CLogger(const CLogger& );
		CLogger& operator=(const CLogger& );

		bool mIsInitialized;
		int mFlags;
		static CLogger* sInstance;
		static pthread_mutex_t sSync;
		std::ofstream mHandle;

#ifndef COMPATIBILITY_LOGGER
		int printl_raw(bool pConsoleOnly, enum ELogLevel pLogLevel, const char* pSource, const char* pFormat, va_list pArgList);
#endif
};

#endif /* __LOGGER_H__ */

